<?php
/*
 * @Descripttion: 
 * @version: 1.0
 * @Author: Sam
 * date: 2021-12-02 11:02:17
 * @LastEditors: Sam
 * @LastEditTime: 2022-03-08 20:24:18
 */
namespace app\api\controller;
use app\__MODULE__\model\{Bargain as BargainModel,BargainDetail,BargainLog,User};
use think\facade\Db;
use hg\apidoc\annotation as Apidoc;

/**
 * @Apidoc\Title("砍价模块")
 */
class Bargain extends Base {

       /**
     * @Apidoc\Title("活动列表")
     * @Apidoc\Url("/api/get_bargain_list")
     * @Apidoc\Method("GET")
     * @Apidoc\Returned ("[]",type="object",desc="活动列表",
     *          @Apidoc\Returned ("id",type="int",desc="活动id"),
     *          @Apidoc\Returned ("title",type="string",desc="标题"),
     *          @Apidoc\Returned ("sub_title",type="string",desc="小标题"),
     *          @Apidoc\Returned ("start_time",type="string",desc="开始时间"),
     *          @Apidoc\Returned ("end_time",type="string",desc="结束时间"),
     *          @Apidoc\Returned ("goods_thumb",type="string",desc="活动图片"),
     *          @Apidoc\Returned ("goods_price",type="string",desc="价格"),
     *          @Apidoc\Returned ("stock",type="string",desc="库存"),
     *          @Apidoc\Returned ("is_join",type="int",desc="是否已参与false 未参与 true 已参与"),
     *     )
     */
    public function list(){
        $uid = self::get_user_id();
        $list = BargainModel::where('is_show',1)->field('id,title,sub_title,start_time,end_time,goods_thumb,goods_price,stock')->order('start_time desc')->select();
        foreach ($list as $key => &$value) {
            if(time() < $value->start_time){
                $status = 0;
            }elseif(time() > $value->end_time){
                $status = 2;
            }else{
                $status = 1;
            }
            $value['start_time']  = date('Y-m-d H:i',$value['start_time']);
            $value['end_time']    = date('Y-m-d H:i',$value['end_time']);
            $value['status_text'] = $status;
            $value['is_join']     = BargainDetail::where(['uid'=>$uid,'aid'=>$value['id']])->count() ? true : false;
        }
        \json_response(1,'success',$list);
    }


       /**
     * @Apidoc\Title("活动详情")
     * @Apidoc\Url("/api/get_bargain_detail")
     * @Apidoc\Method("GET")
     * @Apidoc\Param ("id",type="int",desc="活动id",require=true),
     * @Apidoc\Returned ("detail",type="object",desc="活动详情",
     *          @Apidoc\Returned ("id",type="int",desc="活动id"),
     *          @Apidoc\Returned ("title",type="string",desc="标题"),
     *          @Apidoc\Returned ("sub_title",type="string",desc="小标题"),
     *          @Apidoc\Returned ("start_time",type="string",desc="开始时间"),
     *          @Apidoc\Returned ("end_time",type="string",desc="结束时间"),
     *          @Apidoc\Returned ("goods_thumb",type="string",desc="活动图片"),
     *          @Apidoc\Returned ("goods_price",type="string",desc="价格"),
     *          @Apidoc\Returned ("stock",type="string",desc="库存"),
     *          @Apidoc\Returned ("is_join",type="int",desc="是否已参与false 未参与 true 已参与"),
     *     )
     * @Apidoc\Returned ("bargain",type="object",desc="我的砍价",
     *          @Apidoc\Returned ("order_sn",type="string",desc="订单编号"),
     *          @Apidoc\Returned ("price",type="string",desc="当前价格"),
     *          @Apidoc\Returned ("source_price",type="string",desc="原价"),
     *          @Apidoc\Returned ("pay_status",type="int",desc="支付状态 0 未支付 1已支付"),
     *     )
     * @Apidoc\Returned ("help_log",type="object",default="[]",desc="助力记录 数组结构",
     *          @Apidoc\Returned ("bargain_price",type="string",desc="砍下的价格"),
     *          @Apidoc\Returned ("nickname",type="string",desc="砍价用户昵称"),
     *          @Apidoc\Returned ("avatar",type="string",desc="砍价用户头像"),
     *     )
     */
    public function detail(){
        $aid     = \param_check('id');
        $uid     = self::get_user_id();
        $data    = [];
        if(!$data['detail'] = BargainModel::where(['id'=>$aid,'is_show'=>1])->field('id,title,sub_title,start_time,end_time,goods_thumb,goods_price,stock')->find()) \json_response(0,'未找到砍价活动或已下架');
        $data['detail']['status_text'] = 0; //进行中
        if($data['detail']->start_time > time()){
            $data['detail']['status_text'] = -1; //未开始 
        }elseif($data['detail']->end_time <= time()){
            $data['detail']['status_text'] = 1; //已结束 
        }
        $data['detail']['start_time']  = date('Y-m-d H:i', $data['detail']['start_time']);
        $data['detail']['end_time']    = date('Y-m-d H:i', $data['detail']['end_time']);
        $data['detail']['bargain']     = BargainDetail::where(['uid'=>$uid,'aid'=> $data['detail']['id']])->find();
        $data['detail']['is_join']     = count($data['detail']['bargain'] ) ? true : false;
        $data['help_log']              = BargainLog::with('help')->where(['uid'=>$uid,'aid'=>$data['detail']['id']])->field('id,uid,help_id,bargain_price,create_time')->select(); 
        json_response(1,'success',$data);
    }

    /**
     * @Apidoc\Title("发起砍价")
     * @Apidoc\Url("/api/start_bargain")
     * @Apidoc\Method("POST")
     * @Apidoc\Param ("aid",type="int",desc="活动id",require=true),
     * @Apidoc\Returned ("bid",type="int",desc="砍价记录id")
     */
    public function start_bargain(){
        $uid      = self::get_user_id();
        redis_lock("{$this->redis_key}:start_bargain:{$uid}",$uid,function($uid, $redis){
            $user     = User::find($uid);
            $aid = \param_check('aid');
            if($bargain_detail = BargainDetail::where(['uid'=>$uid,'aid'=>$aid])->find()) return error('该商品已发起砍价');
            $bargain = BargainModel::find($aid);
            if(!$bargain) return error('活动不存在');
            if(!$bargain->stock) return erro('库存不足');
            if(!$bargain->is_show) return error('活动已下线');
            if($bargain->end_time < time()) return error('活动已结束');
            if($bargain->start_time > time()) return error('活动未开始');
            $res =  BargainDetail::create([
                    'uid' => $uid,
                    'aid' => $bargain->id,
                    'order_sn' => BargainDetail::create_order_no('KJ'),
                    'goods_id' => $bargain->goods_id,
                    'price' => $bargain->goods_price,
                    'source_price' => $bargain->goods_price,
                    'bargain_user' =>0
                ]);
            if($bargain->self_bargain ==1){
                //可以自己砍价
                $min_price = $bargain->min_price; //砍价金额最低值
                $max_price = $bargain->max_price; //砍价金额最高值
                $bargain_price = $this->randomFloat($min_price,$max_price); //随机价格
                BargainLog::create([
                    'uid' => $uid,
                    'help_id' => $uid,
                    'aid'   => $bargain->id,
                    'goods_id' => $bargain->goods_id,
                    'bargain_price' => $bargain_price,
                    'create_time'  => time(),
                    'bid'  => $res->id
                ]);
                $res->price -= $bargain_price;
                $res->bargain_user +=1;
                $res->save();
            }
            if($res){
                return success('success',$res->id);
            } 
            return error('error');
        });  
    }



       /**
     * @Apidoc\Title("开始砍价")
     * @Apidoc\Url("/api/share_bargain")
     * @Apidoc\Method("POST")
     * @Apidoc\Param ("bid",type="int",desc="砍价记录id",require=true),
     * @Apidoc\Returned ("price",type="int",desc="砍下的价格")
     */
    public function bargain(){
        $uid = self::get_user_id();
        $id = \param_check('bid'); //用户发起砍价记录ID 也是分享出的传的id值
        redis_lock("{$this->redis_key}:bargain:{$uid}",$uid,function($uid, $redis) use ($id){
            Db::startTrans();
            try{
                if(!$detail = BargainDetail::with('activity')->where('id',$id)->lock(true)->find()) exception('砍价不存在');
                if($detail->stock <=0) exception('该商品已经被抢光了');
                if($detail->status == 1) exception('砍价已完成');
                 if($detail->status == 2) exception('砍价已过期');
                 if($detail->end_time <= time()){
                     $detail->status = 2;
                     $detail->save();
                     exception('砍价已过期');
                 } 
                //  if($detail->uid == $uid && BargainLog::where(['help_id'=>$uid,'bid'=>$id])->count()) exception('不能给自己砍价');
                 $min_price = $detail->activity->min_price; //砍价金额最低值
                 $max_price = $detail->activity->max_price; //砍价金额最高值
                 $bargain_price = $this->randomFloat($min_price,$max_price); //随机价格
                $user = User::find($detail->uid);  //砍价的用户信息 非当前砍价人信息
                if(!$user) exception('对方信息异常');
                if(BargainLog::where(['aid'=>$detail->aid,'uid'=>$detail->uid,'help_id'=>$uid,'bid'=>$id])->whereTime('create_time','d')->count()){
                    exception( '今天已经给TA砍过价了');
                }
    
                 $detail ->price -= $bargain_price;
                 if($detail->price <= $detail->activity->price){
                    //砍价完成
                    $detail->status  =1;
                    $detail ->price = $detail->activity->price;
                    $detail->activity->stock -=1;
                    $detail->pay_status = $detail->activity->price <=0 ? -1 : 0; //如果最低价格设置为可以砍到0 改订单完成 变成-1无需支付 否则变为待支付状态
                    $detail->activity->save();
                 }
                 $detail->bargain_user +=1;
                 $detail->save();
                 BargainLog::create([
                        'uid' => $user->id,
                        'help_id' => $uid,
                        'aid'   => $detail->aid,
                        'goods_id' => $detail->goods_id,
                        'bargain_price' => $bargain_price,
                        'create_time'  => time(),
                        'bid'  => $id
                    ]);
                Db::commit();
            }catch(\Exception $e){
                Db::rollback();
                redis_instance()->del("{$this->redis_key}:bargain:{$uid}");
                json_response(0,$e->getMessage());
            }
            return success('砍价成功',$bargain_price);
        });

    }

       /**
     * @Apidoc\Title("分享详情")
     * @Apidoc\Url("/api/share_bargain_detail")
     * @Apidoc\Method("get")
     * @Apidoc\Param ("bid",type="int",desc="砍价记录id",require=true),
     * @Apidoc\Returned ("aid",type="int",desc="活动id"),
     * @Apidoc\Returned ("title",type="string",desc="标题"),
     * @Apidoc\Returned ("start_time",type="string",desc="开始时间"),
     * @Apidoc\Returned ("end_time",type="string",desc="结束时间"),
     * @Apidoc\Returned ("source_price",type="string",desc="价格"),
     * @Apidoc\Returned ("price",type="string",desc="当前已砍到的价格"),
     * @Apidoc\Returned ("nickname",type="string",desc="发起人昵称"),
     * @Apidoc\Returned ("avatar",type="string",desc="发起人头像"),
     */
    public function share_detail(){
        $id = \param_check('bid');
        if(!$detail = BargainDetail::with(['activity','user'])->where('id',$id)->field('id,uid,aid,goods_id,status,price,source_price')->find()) {
            json_response('砍价不存在');
        }
        $detail->start_time = date('Y年m月d日',($detail->start_time));
        $detail->end_time = date('Y年m月d日',($detail->end_time));
        \json_response(1,'success',$detail);
    }

        /**
     * @Apidoc\Title("砍价订单支付")
     * @Apidoc\Url("/api/bargain_pay")
     * @Apidoc\Method("post")
     * @Apidoc\Param ("order_sn",type="int",desc="订单编号",require=true),
     * @Apidoc\Returned ("js_config",type="object",desc="支付参数",
     *          @Apidoc\Returned ("timeStamp",type="string",desc="时间戳"),
     *          @Apidoc\Returned ("nonceStr",type="string",desc="随机字符串"),
     *          @Apidoc\Returned ("signType",type="string",desc="加密方式"),
     *          @Apidoc\Returned ("paySign",type="string",desc="签名")
     *     )
     */
    public  function  bargain_pay(){
        $uid = self::get_user_id();
        $order_sn = \param_check('order_sn');
        $order    = BargainDetail::where(['order_sn'=>$order_sn,'uid'=>$uid])->find();
        !$order   && \json_response(0,'订单不存在');
        !$order->status && json_response(0,'砍价未完成');
        $order->status== -1 && json_response(0,'订单不需支付');
        $order->pay_status ==1 && json_response(0,'订单已支付');
        $wechat_server = new \app\common\api\WeChat();
        $jsConfig = $wechat_server->pay_param(User::where('id',$uid)->value('openid'),$order->order_sn,$order->price, str_replace(request()->pathinfo(),'api/notify',request()->url(true)));
        $info['js_config'] = $jsConfig;
        json_response(1,'success',$info);
    }



    /**
     * 支付回调
     * @return [type] [description]
     */
    public function notify(){
        $wechat_server = new \app\common\api\WeChat();
        $wechat_server->check_sign(function($data){
             Db::startTrans();
             try{
                  $order = BargainDetail::where('order_sn',$data['out_trade_no'])->find();
                  if($order && !$order->pay_status){
                     $order->pay_status         = 1;
                     $order->pay_time       = time();
                     $order->transaction_id = $data['transaction_id'];
                     $order->total_fee      = $data['total_fee'];
                     $order->save();
                     $order->activity->stock -= 1;
                     $order->activity->save();
                 }
                 Db::commit();
             }catch(\Excepion $e){
                 Db::rollback();
             }
            
        });
     }

    function randomFloat($min = 0, $max = 1) {
        return round($min + mt_rand() / mt_getrandmax() * ($max - $min),2);
    }
    
}
